package org.example.structure.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 类描述：使用Cglib实现动态代理
 * <br>
 *
 * @author ZS
 * @version 1.0
 * @date 2020/12/29
 **/
public class CglibProxyDemo1 {
    public static void main(String[] args) {
        // 1.创建目标对象
        User user = new User();
        // 2.创建增强器
        CglibProxy<User> cglibProxy = new CglibProxy<>(user);
        // 3.获取代理对象
        User proxy = cglibProxy.getProxy();

        String say = proxy.say(10, "世界");
        System.out.println(say);
    }

    static class CglibProxy<T> implements MethodInterceptor {

        private final T t;

        public CglibProxy(T t) {
            this.t = t;
        }

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            // 前置增强
            before(method, objects);

            // 目标方法执行
            Object ret = methodProxy.invoke(t, objects);

            // 后置增强
            after(ret, method, objects);
            return ret;
        }

        // 获得代理对象
        @SuppressWarnings("unchecked")
        public T getProxy() {
            // 1.创建Enhancer
            Enhancer enhancer = new Enhancer();
            // 2.设置目标类的类型
            enhancer.setSuperclass(t.getClass());
            // 3.设置增强回调
            enhancer.setCallback(this);

            return (T) enhancer.create();
        }

        private void after(Object ret, Method method, Object[] objects) {
            System.out.println("方法的返回值：" + ret);
        }

        private void before(Method method, Object[] objects) {
            System.out.println("执行的方法：" + method.getName());
            System.out.println("传入的参数：" + Arrays.toString(objects));
        }
    }

    static class User {
        public String say(Integer a, String b) {
            System.out.println("执行目标方法！");
            return "返回值";
        }
    }
}
